﻿using System.Collections.Generic;
using System;

namespace SixthSense
{
    class ObjectInfo
    {
        float _Divisor = 192.0F;

        private int _ID = 0;
        private bool _Selectable = false;
        private int _Landblock = 0;
        private double _NSCoordinate = 0;
        private double _EWCoordinate = 0;
        private double _RelativeNSCoord = 0;
        private double _RelativeEWCoord = 0;
        private string _NS;
        private string _EW;
        private string _Name;
        private string _Type;
        private string _Text;
        private int _Icon = 0;
        private int _Value;
        MaterialInfo _Material;

        public int Value
        {
            get
            {
                return _Value;
            }
            set
            {
                _Value = value;
            }
        }

        public MaterialInfo Material
        {
            get
            {
                return _Material;
            }
            set
            {
                _Material = value;
            }
        }

        public string Text
        {
            get
            {
                return _Text;
            }
            set
            {
                _Text = value;
            }
        }

        public string Type
        {
            get
            {
                return _Type;
            }
            set
            {
                _Type = value;
            }
        }

        public string Name
        {
            get
            {
                return _Name;
            }
            set
            {
                _Name = value;
            }
        }

        public int Icon
        {
            get
            {
                return _Icon;
            }
            set
            {
                _Icon = value;
            }
        }

        public int ID
        {
            get
            {
                return _ID;
            }
            set
            {
                _ID = value;
            }
        }

        public bool Selectable
        {
            get
            {
                return _Selectable;
            }
            set
            {
                _Selectable = value;
            }
        }

        public int Landblock
        {
            get
            {
                return _Landblock;
            }
            set
            {
                _Landblock = value;
            }
        }

        // MUST set landblock before setting xOffset
        public float xOffset
        {
            set
            {
                float f1 = 0;

                f1 = (float)((_Landblock & 0xff000000) >> 24);

                if (f1 < 3)
                {
                    _EWCoordinate = (float)(value / 12.0F) / 10.0F;
                }
                else
                {
                    _EWCoordinate = (float)(((f1 + 1) * 8.0F + (value * 8.0F) / _Divisor) - 1027.5F) / 10.0F;
                }

                MakeEWString();
            }
        }

        // MUST set landblock before setting yOffset
        public float yOffset
        {
            set
            {
                float f1 = 0;
                float f2 = 0;

                float fDivisor = 192.0F;

                f1 = (float)((_Landblock & 0xff000000) >> 24);
                f2 = (float)((_Landblock & 0x00ffffff) >> 16);

                if (f1 < 3)
                {
                    _NSCoordinate = (float)(value / 12.0F) / 10.0F;
                }
                else
                {
                    _NSCoordinate = (float)(((f2 + 1) * 8.0F + (value * 8.0F) / fDivisor) - 1027.5F) / 10.0F;
                }

                MakeNSString();
            }
        }

        public double NSCoordinate
        {
            get
            {
                return _NSCoordinate;
            }
            set
            {
                _NSCoordinate = value;
                MakeNSString();
            }
        }

        public double EWCoordinate
        {
            get
            {
                return _EWCoordinate;
            }
            set
            {
                _EWCoordinate = value;
                MakeEWString();
            }
        }

        public string Coords
        {
            get
            {
                return _NS + " " + _EW;
            }
        }

        public string GetRelativeCoords(ObjectInfo RelativeObject)
        {
            _RelativeNSCoord = RelativeObject.NSCoordinate;
            _RelativeEWCoord = RelativeObject.EWCoordinate;

            MakeEWString();
            MakeNSString();

            return _NS + " " + _EW;
        }

        private void MakeNSString()
        {
            // if the relative coord is not set, it shouldnt affect the math
            double tmpNSCoord = _NSCoordinate - _RelativeNSCoord;

            if (tmpNSCoord >= 10.0 || tmpNSCoord <= -10.0)
            {
                _NS = string.Format("{0:F1}", Math.Abs(tmpNSCoord));
            }
            else
            {
                _NS = string.Format("{0:F2}", Math.Abs(tmpNSCoord));
            }

            if (tmpNSCoord < 0)
            {
                // negative is south
                _NS += "S";
            }
            else
            {
                _NS += "N";
            }
        }

        private void MakeEWString()
        {
            // if the relative coord is not set, it shouldnt affect the math
            double tmpEWCoord = _EWCoordinate - _RelativeEWCoord;

            if (tmpEWCoord >= 10.0 || tmpEWCoord <= -10.0)
            {
                _EW = string.Format("{0:F1}", Math.Abs(tmpEWCoord));
            }
            else
            {
                _EW = string.Format("{0:F2}", Math.Abs(tmpEWCoord));
            }

            if (tmpEWCoord < 0)
            {
                // negative is west
                _EW += "W";
            }
            else
            {
                _EW += "E";
            }
        }
    }

    class ObjectInfoList : List<ObjectInfo>
    {
        public ObjectInfo FindById(int Item)
        {
            ObjectInfo FoundObject = this.Find(o => o.ID == Item);

            return FoundObject;
        }

        public bool Delete(int ItemId)
        {
            ObjectInfo FoundObject = FindById(ItemId);

            if (FoundObject != null)
            {
                this.Remove(FoundObject);
                return true;
            }

            return false;
        }
    }
}
